package communication;


import java.io.IOException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.ConsumerCancelledException;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.ShutdownSignalException;


/**
 * Deze klasse zit tussen RabbitMQ en het GhostProtocol.
 * 
 * @author	Team Zilver
 */
public class RabbitMQKanaalUiteinde extends ReeelKanaalEinde implements Runnable{
	
	private Channel channel;
	private String exchange;
	private String host;
	private QueueingConsumer consumer;
	
	/**
	 * Creates a new RabbitMQKanaalUiteinde.
	 * 
	 * @throws	KanInitieleVerbindingNietMaken
	 * 			Could not make the initial connection.
	 */
	public RabbitMQKanaalUiteinde(String host, String exchange) {
		
		this.exchange = exchange;
		this.host = host;
		
		initVerbinding();
		
		Thread dit = new Thread(this);
		dit.setName("RabbitMQ");
		dit.start();
	}
	
	//Channel
	private Channel getChannel(){
		return channel;
	}
	
	private void setChannel(Channel c){
		this.channel = c;
	}
	
	@Override
	protected void stuurSpecifiek(byte[] bericht) throws IOException {
		getChannel().basicPublish(exchange, "", null, bericht);
	}

	@Override
	protected boolean connect() {
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost(host);
		
		try {
			Connection connection = factory.newConnection();
			
			Channel channel = connection.createChannel();
			
			channel.exchangeDeclare(exchange, "fanout");
			String queueNaam = channel.queueDeclare().getQueue();
			
			channel.queueBind(queueNaam, exchange, "");
			
			consumer = new QueueingConsumer(channel);
			
			channel.basicConsume(queueNaam, consumer);
			
			setChannel(channel);
		} catch (IOException e) {
			return false;
		}
		
		
		
		setConnected();
		
		return true;
	}

	@Override
	protected void onDisconnect() {
		while(connect() != true);
		{
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
			}
		}
	}


	@Override
	public void run() {

		while(true)
		{
			try {
				byte[] body = consumer.nextDelivery().getBody();
				getProtocol().verwerkInkomend(body);
				
			} catch (ShutdownSignalException e) {
				setDisconnected();
			} catch (ConsumerCancelledException e) {
				setDisconnected();
			} catch (InterruptedException e) {
				setDisconnected();
			}
		}
	}

}
